package me.helllp.book.concurrent.ch04;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * 使用AtomicStampedReference解决ABA问题
 * 
 * @author Administrator
 *
 */
public class CasAbaDemo {
	private static AtomicInteger atomicInt = new AtomicInteger(100);
	private static AtomicStampedReference<Integer> stampedRef = new AtomicStampedReference<Integer>(100, 0);
	
	public static void main(String[] args) throws InterruptedException {
		Thread t1 = new Thread(new Runnable() {
			public void run() {
				atomicInt.compareAndSet(100, 101);
				atomicInt.compareAndSet(101, 100);
				
			}
		});
		
		Thread t2 = new Thread(new Runnable() {
			public void run() {
				try {
					TimeUnit.SECONDS.sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				boolean c3 = atomicInt.compareAndSet(100, 101);
				System.out.println("ABA比较结果：" + c3);
			}
		});
		
		t1.start();
		t2.start();
		t1.join();
		t2.join();
		
		Thread ref1 = new Thread(new Runnable() {
			public void run() {
				try {
					TimeUnit.SECONDS.sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				stampedRef.compareAndSet(100, 101, stampedRef.getStamp(), stampedRef.getStamp() + 1);
				stampedRef.compareAndSet(101, 100, stampedRef.getStamp(), stampedRef.getStamp() + 1);
			}
		});
		
		Thread ref2 = new Thread(new Runnable() {
			public void run() {
				int stamp = stampedRef.getStamp();
				try {
					TimeUnit.SECONDS.sleep(2);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				boolean c3 = stampedRef.compareAndSet(100, 101, stamp, stamp+1);
				System.out.println("ABA改善比较结果：" + c3);				
			}
		});
		
		ref1.start();
		ref2.start();
	}
}
